package com.ce.pms.system.custservice.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.ce.pms.base.vo.SearchVO;
import com.ce.pms.common.dao.ISysrefcodeDao;
import com.ce.pms.common.model.SysInfo;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.system.custservice.dao.ICustEventKindDao;
import com.ce.pms.system.custservice.dao.ICustEventNatureDao;
import com.ce.pms.system.custservice.model.CustEventKindDO;
import com.ce.pms.system.custservice.model.CustEventNatureDO;
import com.ce.pms.system.custservice.vo.CustEventKindVO;
import com.sitechasia.webx.core.support.Page;

/**
 * 描述：测试“事件类型”service
 * @author 王浩羽
 *
 */
public class CustEventKindServiceImplT extends MyJMockBaseTestCase
{

	private CustEventKindServiceImpl custEventKindServiceImpl;
	private ICustEventKindDao custEventKindDao;
	private ICustEventNatureDao custEventNatureDao;
	private CustEventKindVO kindVO ;
	private CustEventKindDO kindDO ;
	
	//常量数据
	private final Long CURRENT_ID = 2008L;
	private final String CURRENT_NAME = "oldName";
	private final String CURRENT_REMARK = "oldRemark";
	private final short CURRENT_SEQUENCE = (short)1;
	
	private final Long NEW_ID = 2009L;
	private final String NEW_NAME = "newName";
	private final String NEW_REMARK = "newRemark";
	private final short NEW_SEQUENCE = (short)2;
	private final Long EVENT_NATURE_ID = 303L;
	
	@Before
	public void setUp() throws Exception
	{
		super.setUp();
		custEventKindDao = context.mock(ICustEventKindDao.class);
		custEventNatureDao = context.mock(ICustEventNatureDao.class);
		custEventKindServiceImpl = new CustEventKindServiceImpl();
		custEventKindServiceImpl.setCustEventKindDao(custEventKindDao);
		custEventKindServiceImpl.setCustEventNatureDao(custEventNatureDao);
		custEventKindServiceImpl.setSysrefcodeDao(sysrefcodeDao);
		
		kindVO = new CustEventKindVO();
		kindDO = new CustEventKindDO();
		
		kindDO.setKeyword(CURRENT_ID);
		kindDO.setName(CURRENT_NAME);
		kindDO.setRemark(CURRENT_REMARK);
		kindDO.setSequence(CURRENT_SEQUENCE);
		
		//添加SysInfo
		kindDO.setSysInfo(sysInfo);
		
		//VO暂不设置ID，如果VO有ID，使用NEW_ID
		kindVO.setName(NEW_NAME);
		kindVO.setRemark(NEW_REMARK);
		kindVO.setSequence(NEW_SEQUENCE);
		kindVO.setEventNatureId(EVENT_NATURE_ID);
	}


	@After
	public void tearDown() throws Exception
	{
		super.tearDown();
	}


	@Test
	public void testAddCustEventKindFail()
	{
		kindVO.setName(kindDO.getName());
		kindVO.setCreator(SYSTEM_INFO_CREATER);
		// expectations
		context.checking(new Expectations() {{
			//当名称存在时，将抛出异常，保存操作不会执行
			oneOf(custEventKindDao).findUniqueByName(kindVO.getName()); will(returnValue(kindDO));
			never(custEventNatureDao).findById(kindVO.getEventNatureId());
			never(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));	
			never(custEventKindDao).saveObject(with(any(CustEventKindDO.class))); 
	    }});
		// execute
		try
		{
			boolean returnValue = custEventKindServiceImpl.addCustEventKind(kindVO);
			fail("it should throw exception!");
		}
		catch(Exception e)
		{
			assertTrue(e instanceof BusinessException);
		}
		// verify
		context.assertIsSatisfied();
	}

	@Test
	public void testAddCustEventKindSuccess(){
		kindVO.setCreator(SYSTEM_INFO_CREATER);
		
		final CustEventNatureDO eventNatureDO = new CustEventNatureDO();
		eventNatureDO.setKeyword(kindVO.getEventNatureId());
		// expectations
		context.checking(new Expectations() {{
			//当名称还没有存在时，保存操作执行
			oneOf(custEventKindDao).findUniqueByName(kindVO.getName()); will(returnValue(null));
			oneOf(custEventNatureDao).findById(kindVO.getEventNatureId());will(returnValue(eventNatureDO));
			oneOf(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
			oneOf(custEventKindDao).saveObject(with(any(CustEventKindDO.class))); will(returnValue(kindDO));
	    }});
		// execute
		boolean returnValue = custEventKindServiceImpl.addCustEventKind(kindVO);
		// verify
		context.assertIsSatisfied();
		assertTrue(returnValue);
	}

	@Test
	public void testDeleteCustEventKindByIdFail()
	{
		// expectations
		context.checking(new Expectations() {{
			//抛出异常
			oneOf(custEventKindDao).deleteObjectById(CURRENT_ID);will(throwException(new RuntimeException("被引用")));
	    }});
		// execute
		try
		{
			boolean returnValue = custEventKindServiceImpl.deleteCustEventKindById(CURRENT_ID);
			fail("it should throw exception!");
		}
		catch(Exception e)
		{
			assertTrue(e instanceof BusinessException);
		}
		// verify
		context.assertIsSatisfied();
	}

	@Test
	public void testDeleteCustEventKindByIdSuccess(){
		// expectations
		context.checking(new Expectations() {{
			//不抛异常
			oneOf(custEventKindDao).deleteObjectById(CURRENT_ID);
	    }});
		// execute
		try
		{	
			boolean returnValue = custEventKindServiceImpl.deleteCustEventKindById(CURRENT_ID);
			assertTrue(returnValue);
		}
		catch(Exception e)
		{
			fail("it should not throw exception! "+e.getMessage());
		}
		// verify
		context.assertIsSatisfied();
	}

	@Test
	public void testEditCustEventKindFail()
	{
		kindVO.setKeyword(NEW_ID);	
		kindVO.setModifier(SYSTEM_INFO_NEW_MODIFIER);
		// expectations
		context.checking(new Expectations() {{
			//当数据库没有存在待修改记录时,不在进行修改操作
			oneOf(custEventKindDao).findById(kindVO.getKeyword()); will(returnValue(null));
			never(custEventNatureDao).findById(kindVO.getEventNatureId());
			never(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
			never(custEventKindDao).updateObject(with(any(CustEventKindDO.class)));
	    }});
		// execute
		boolean returnValue = custEventKindServiceImpl.editCustEventKind(kindVO);
		// verify
		context.assertIsSatisfied();
		assertFalse(returnValue);
	}
	
	@Test
	public void testEditCustEventKindSuccess()
	{
		kindVO.setKeyword(CURRENT_ID);
		kindVO.setModifier(SYSTEM_INFO_NEW_MODIFIER);
		final Long NEW_EVENT_NATURE_ID = 304L;
		kindVO.setEventNatureId(NEW_EVENT_NATURE_ID);
		final CustEventKindDO kindDO_toEdit = new CustEventKindDO();
		copyData(kindDO, kindDO_toEdit);
		kindDO_toEdit.setKeyword(kindVO.getKeyword());
		
		final CustEventNatureDO eventNatureDO = new CustEventNatureDO();
		eventNatureDO.setKeyword(kindVO.getEventNatureId());
		
		// expectations
		context.checking(new Expectations() {{
			//当数据库存在待修改记录时,
			oneOf(custEventKindDao).findById(kindVO.getKeyword()); will(returnValue(kindDO_toEdit));
			oneOf(custEventNatureDao).findById(kindVO.getEventNatureId());will(returnValue(eventNatureDO));
			oneOf(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
			//进行修改操作
			oneOf(custEventKindDao).updateObject(kindDO_toEdit); will(returnValue(kindDO_toEdit));
	    }});
		// execute
		boolean returnValue = custEventKindServiceImpl.editCustEventKind(kindVO);
		// verify
		context.assertIsSatisfied();
		assertTrue(returnValue);
		//数据已经被更改
		assertEquals(kindVO.getRemark(), kindDO_toEdit.getRemark());
		assertTrue(kindVO.getSequence()==kindDO_toEdit.getSequence());
		assertTrue(kindVO.getEventNatureId()==kindDO_toEdit.getCustEventNature().getKeyword());
	}
	
	@Test
	public void testQueryCustEventKind()
	{
		final Long eventKindId = 2008L;
		final List<CustEventKindDO> eventKindDOList = new ArrayList<CustEventKindDO>();
		final int listSize = 10;
		for(int i = 0; i < listSize; i++)
		{
			eventKindDOList.add(new CustEventKindDO());
		}
		
		context.checking(new Expectations() {{
			oneOf(custEventKindDao).queryCustEventKind(eventKindId); will(returnValue(eventKindDOList));
	    }});
		List<CustEventKindVO> returnValue = custEventKindServiceImpl.queryCustEventKind(eventKindId);
		context.assertIsSatisfied();
		assertTrue(returnValue.size()==listSize);
		assertTrue(eventKindDOList.size()==returnValue.size());
	}


	@Test
	public void testQueryCustEventKindListByPage()
	{
		final SearchVO searchVO = new SearchVO();
		Integer currentPage = 2; 
		Integer pageSize = 5;
		searchVO.setPageNo(currentPage);
		searchVO.setPageSize(pageSize);
		
		final Page page = new Page();
		context.checking(new Expectations() {{
			oneOf(custEventKindDao).queryByPage(searchVO); will(returnValue(page));
	    }});
		Page returnValue = custEventKindServiceImpl.queryCustEventKindListByPage(searchVO);
		context.assertIsSatisfied();
		assertNotNull(returnValue);
	}

}
